/**************************************************************************************
 *  Copyright (c)  2010 Changmin Bae, Leszek Karcz.
 *  Permission is granted to copy, distribute and/or modify this document
 *  under the terms of the GNU Free Documentation License, Version 1.3
 *  or any later version published by the Free Software Foundation;
 *  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 *  A copy of the license is included in the section entitled "GNU
 *  Free Documentation License". 
 **************************************************************************************/
package data.tileables;
import data.Map;
import data.Player;
import data.StructLinkedList;
import data.Tile;
import data.missions.PowerDown;
import data.missions.PowerUp;
import data.missions.UnassignAll;

/**************************************************************************************
 * Author(s): Leszek Karcz, Changmin Bae
 * Base building, the main building for a player
 **************************************************************************************/
public abstract class HarvestStructure extends Structure
{
	//private assigned workers
	
	//allocations
	
	protected StructLinkedList harvest;
	private int harvestType;
	private int unassignedWorkers;
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * Base constructor
	 **************************************************************************************/
	public HarvestStructure(int ID, int supertypeID, Player player, int workers)
	{
		super(ID, supertypeID, player, workers);
		this.setType("StaffedStructure");
		unassignedWorkers = workers;
	}
	
	/**************************************************************************************
	 * Author(s): Changmin Bae
	 * returns the harvest StructLinkedList
	 **************************************************************************************/
	public StructLinkedList getHarvestList()
	{
		return harvest;
	}

	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * This will return the type of harvest in int form
	 * 		FOOD   = 0
	 * 		METAL  = 1
	 * 		ENERGY = 2
	 **************************************************************************************/
	protected int getHarvestType(){ return harvestType; }
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * This will return the type of havest in int form
	 * 		FOOD   = 0
	 * 		METAL  = 1
	 * 		ENERGY = 2
	 **************************************************************************************/
	protected void setHarvestType(int type){ 
		if(harvestType == 0) 
			harvestType= type; 
	}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor, Changmin Bae
	 * This will return the amount that was harvested
	 * 	 	FOOD   = 0
	 * 		METAL  = 1
	 * 		ENERGY = 2
	 **************************************************************************************/
	public int [] harvest(){
		if(harvest!=null)
		{
			int resources = harvest.harvest();
			int [] temp = new int[3];
			temp[getHarvestType()] = resources;
			return temp;
		}
		else
		{
			return new int[]{0,0,0};
		}
	}
	
	/**************************************************************************************
	 * Author(s): Changmin Bae
	 * executes instructions regarding currently selected command
	 **************************************************************************************/
	public boolean enqueueSelectedCommand(String mode, Map m, int x, int y)
	{
		
		if(this.isFinished())
		{
			if((this.getCommandMode()==0) && (mode.equals("Issue")))
			{
				switch(this.getSelectedCommand())
				{
				
				case 0:
					this.die();
					break;
				case 1:
					if(this.getState() == 0)
						this.addMission(new PowerUp(this));
					else
						this.addMission(new PowerDown(this));
					break;
				case 2:
						this.setCommandMode(1);
					break;
				case 3:
					this.addMission(new UnassignAll(this));		
					break;
				}				
			}
			else if((this.getCommandMode()==1))
			{
				if(mode.equals("Issue"))
				{
					this.setCommandMode(0);
						this.assignWorkers(this.getCommandValue(), m, x, y, 0);
					this.setCommandValue(0);
				}
				else
				{
					boolean flag=false;
					try  
					{  
						Integer.parseInt(mode);  
						flag=true;
					}  
					catch(Exception e){}  
					if(flag)
					{
						this.setCommandValue(Integer.parseInt(mode));
					}
				}
			}
		}	
		else
		{
			switch(this.getSelectedCommand())
			{			
				case 0:
					this.die();
			}
		}
		
		return true;
	}
	
	/**************************************************************************************
	 * Author(s): Changmin Bae
	 * returns list of possible commands
	 **************************************************************************************/
	public String[] getCommandsText()
	{
		if(this.isFinished())
		{
			if(this.getCommandMode()==0)
			{			
				return new String[]{"Decommision",(this.getState()==0 ? "Power up" : "Power down"),"Assign workers","Unassign all"};
			}
			else if(this.getCommandMode()==1)
			{
				return new String[]{"Workers: "+this.getCommandValue()};
			}
			else
			{
				 return new String[]{"---"};
			}
		}
		else
		{
			return new String[]{"Cancel"};
		}
	}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * Add a tile to be harvested
	 * 	 	True = tile was succesfully added
	 * 		False = tile was not added
	 **************************************************************************************/
	public void addResource(Resources tile){
		if(tile == null)
			return;
		
		harvest.addResource(tile, this);
	}
	
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * Get unassigned workers as an int
	 **************************************************************************************/
	public int getUnassignedWorkers(){	return this.unassignedWorkers;}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * decrements unassigned workers as an int
	 **************************************************************************************/
	public int decUnassignedWorkers(int num){	
		if(num > unassignedWorkers)
			num = unassignedWorkers;
		
		unassignedWorkers -=num;
		
		return num;
	}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * increments unassigned workers
	 **************************************************************************************/
	public void incUnassignedWorkers(int num){unassignedWorkers += num;}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * Remove a tile to be harvested
	 * 	 	True = tile was succesfully removed
	 * 		False = tile was not not found
	 **************************************************************************************/
	public boolean removeTile(Resources tile){return harvest.remove(tile);}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * Assign unassigned workers to a tile
	 * 		-1 = Tile not found
	 * 		> -1 = Tile was found and workers were assigned
	 **************************************************************************************/
	public int assignWorkers(int num, Resources r){
		
		if(num > unassignedWorkers)
			num = unassignedWorkers;
		
		if(!harvest.assignWorkers(num, r))
			return -1;
					
		unassignedWorkers -= num;

		return num;
	}
	
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * Add more workers to the structure. They are unassigned to a tile
	 * 		True = successful
	 * 		False = fail
	 **************************************************************************************/
	public boolean addWorkers(int amount){
		
		if(!super.addWorkers(amount))
			return false;		
			
		unassignedWorkers +=amount;

		return true;
	}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * Remove workers to the structure. This takes from the unassigned workers
	 * 		True = successful
	 * 		False = fail
	 **************************************************************************************/
	public int removeWorkers(int amount){
		
		if(unassignedWorkers - amount < 0){
			int temp = unassignedWorkers;
			unassignedWorkers = 0;
			super.removeWorkers(temp);
			return temp;
		}
			
		 unassignedWorkers -= amount;
		 super.removeWorkers(amount);

		return amount;
	}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * Initializes the structure list
	 **************************************************************************************/
	protected void initializeList(int type){ harvest = new StructLinkedList(type);}
	
	
	/**************************************************************************************
	 * Author(s): Changmin Bae
	 * Assigns workers to a tile
	 **************************************************************************************/
	public boolean assignWorkers(int workers, Map map, int x, int y, int type){
		
		if(!(map.checkRadius(this.getX(), getY(), x, y, this.getVisionRadius())))
			return false;
		
		Tile temp = map.getTile(x, y);
		
		if(temp.getResources() == null)
			return false;
		
		
		addResource(temp.getResources());
		this.assignWorkers(workers, temp.getResources());
		
		
		return true;
	}
	
	public String[] getStatsText(){
		String []test = super.getStatsText().clone();
		test[8] = "Workers "+this.getUnassignedWorkers()+"/"+this.getWorkerCount();
		return test;
	}
}

